home *** CD-ROM | disk | FTP | other *** search
- cseg segment para public 'code'
- org 100h
- keymod proc far
-
- keyaddr equ 9h*4 ; keyboard interrupt address
- vidaddr equ 10h*4 ; video interrupt address
- usraddr equ 61h*4 ; user interrupt address
- whozat equ 1235h ; signature value
-
- ; Memory-resident program to intercept keyboard interrupts.
- ; Once loaded, this program will remain resident until DOS is reloaded.
- ; The program can be re-run, to change the original options.
- ; This program is used to control the state of the following keys:
- ;
- ; Caps Lock : U+ (force on), U- (force off), or U (normal)
- ; Num Lock : N+ (force on), N- (force off), or N (normal)
- ; Alt Key : A+ (force on), A- (force off), or A (normal)
- ; Ctrl Key : C+ (force on), C- (force off), or C (normal)
- ; Left Shift : L+ (force on), L- (force off), or L (normal)
- ; Right Shift: R+ (force on), R- (force off), or R (normal)
- ; Boot : B+ or B (on - normal) or B- (off - disabled)
- ; Ctrl-Break : X+ or X (on - normal) or X- (off - disabled)
- ; Suspend : S+ (enable pause), S- or S (normal - no effect)
- ; Reset all keys to normal: *
- ;
- ; For example, 'KEYMOD U+ B- X-' would force caps lock on, disable booting via
- ; Alt-Ctrl-Del, and disable Ctrl-Break.
-
- assume cs:cseg,ds:cseg,ss:nothing,es:nothing
- jmp p100 ; start-up code
-
- keyint dd 0 ; keyboard interrupt vector
- vidint dd 0 ; video interrupt vector
- signature dw whozat ; program's signature
-
- ; keyboard mod table
- ; 0 = no change, 1 = force off, 2 = force on
- modtbl db 0ffh ; insert - not used
- db 0 ; caps lock
- db 0 ; num lock
- db 0ffh ; suspend - used below
- db 0 ; alt
- db 0 ; ctrl
- db 0 ; left shift
- db 0 ; right shift
- noboot db 0 ; disable boot if 1
- nobreak db 0 ; disable ctrl-break if 1
- suspend db 0 ; enable suspend key if 2
- tstack db 16 dup ('stack ') ; temporary stack
- estack db 0 ; end of temp stack
- holdss dw 0 ; original ss
- holdsp dw 0 ; original sp
-
- p000: sti ; interrupt (resident) code starts here
- push ax ; save registers
- push cx
- push es
- push di
- pushf
-
- mov ax,40h
- mov es,ax
- mov di,17h ; point to keyboard flag
- mov ah,es:[di] ; keyboard state - flag in ah
-
- mov cx,8
- mov di,offset modtbl ; point to mod table
- p010: mov al,cs:[di] ; get mod value
- cmp al,1 ; turn key off?
- jz p020 ; yes
- cmp al,2 ; turn key on?
- jz p015 ; yes
- jmp p030 ; do nothing with this one
-
- p015: mov al,1 ; turn key on
- rol al,cl ; rotate left
- ror al,1 ; back 1
- or ah,al ; switch bits on in ah
- jmp p030
-
- p020: mov al,1 ; turn key off
- rol al,cl
- ror al,1
- xor al,0ffh ; flip the bits
- and ah,al ; switch bits off in ah
-
- p030: inc di
- loop p010 ; continue
-
- mov al,cs:[noboot] ; is boot disabled?
- cmp al,1
- jnz p040 ; no
- test ah,08h ; alt pressed?
- jz p040 ; no
- test ah,04h ; ctrl pressed?
- jz p040 ; no
- and ah,0fbh ; tried alt-ctrl-del, turn off ctrl!
-
- p040: test ah,04h ; is ctrl pressed?
- jz p050 ; no
- mov al,cs:[nobreak] ; is ctrl-break disabled?
- cmp al,1
- jnz p050 ; no
- in al,60h ; get next char from kybd
- cmp al,46 ; is it a 'c'?
- jz p045 ; yes
- cmp al,70 ; is it a break?
- jz p045 ; yes
- jmp p050
- p045: and ah,0fbh ; turn off ctrl!
-
- p050: mov di,17h
- mov es:[di],ah
- popf
- pop di
- pop es
- pop cx
- pop ax
- jmp cs:[keyint]
-
- p060: sti ; resident code for video interrupt
- push ax ; save registers
- push di
- push es
-
- mov al,cs:[suspend] ; is suspend on?
- cmp al,2
- jnz p070 ; no
- mov di,40h
- mov es,di
- mov di,17h ; point to keyboard flag
- mov al,es:[di] ; get keyboard flag
- test al,10h ; check suspend
- jz p070 ; it's off
- cmp ah,7 ; scroll down?
- jz p065 ; yes
- cmp ah,6 ; scroll up?
- jnz p070 ; no
-
- p065:
- cli ; no interrupts
- mov ax,ss ; save original stack
- mov cs:[holdss],ax
- mov cs:[holdsp],sp
- mov ax,cs ; point to temp stack
- mov ss,ax ; make ss=cs
- mov sp,offset estack
- sti ; allow interrupts
-
- mov ah,0 ; wait for a key to be pressed
- int 16h
-
- cli ; no interrupts
- mov ax,cs:[holdss] ; restore original stack
- mov ss,ax
- mov sp,cs:[holdsp]
- sti ; allow interrupts
-
- mov di,17h
- mov al,es:[di] ; keyboard state - flag in al
- and al,0efh ; turn suspend off
- mov es:[di],al ; re-set state
-
- p070: pop es
- pop di
- pop ax
- jmp cs:[vidint] ; jump to video interrupt
-
-
- p100: ; transient code starts here
- call p120 ; get current keyboard vector
- call p140 ; decode command line
- call p160 ; turn suspend off
- call p180 ; display key settings
- mov al,firstime
- cmp al,1 ; first time?
- jz p105 ; yes - leave resident
- int 20h ; no - vanish!
-
- p105: mov dx,offset p100 ; last byte of resident portion
- int 27h ; terminate
-
- p120 proc near ; get current keyboard buffer
- mov dx,offset copyr
- call p200 ; display copyright
- mov di,usraddr+2 ; point to user interrupt
- mov ax,0
- mov es,ax
- mov bx,es:[di] ; get current contents
- mov es,bx ; make it the segment
- mov di,offset signature
- mov cx,es:[di] ; get signature
- cmp cx,whozat ; is it this program?
- jz p125 ; yes - don't install it
-
- mov ax,0
- mov es,ax
- mov di,keyaddr ; point to keyboard interrupt
- mov ax,es:[di] ; get current ip
- mov bx,es:[di+2] ; get current cs
- mov si,offset keyint ; save address
- mov [si],ax
- mov [si+2],bx
-
- mov di,vidaddr ; point to video interrupt
- mov ax,es:[di] ; get current ip
- mov bx,es:[di+2] ; get current cs
- mov si,offset vidint ; save address
- mov [si],ax
- mov [si+2],bx
-
- mov al,1 ; first time through
- mov firstime,al ; set first time flag
- mov dx,offset install
- call p200
- mov ax,0
- mov es,ax
- mov bx,ds
- cli ; no interrupts
-
- mov di,keyaddr
- mov ax,offset p000
- mov es:[di],ax ; change keyboard interrupt
- mov es:[di+2],bx
-
- mov di,vidaddr
- mov ax,offset p060
- mov es:[di],ax ; change video interrupt
- mov es:[di+2],bx
-
- mov di,usraddr ; set user interrupt - segment only
- mov ax,offset signature
- mov es:[di],ax
- mov es:[di+2],bx
-
- sti ; allow interrupts again
-
- push cs
- pop bx ; get current cs
-
- p125: mov si,offset realcs
- mov [si],bx ; save real cs
- ret
- p120 endp
-
- p140 proc near ; decode command line
- mov si,80h ; point to command line
- mov ch,0
- mov cl,[si] ; get length
- jcxz p159 ; length is zero
- push cx ; save length
- inc si ; point to first char
- push si ; save start addr
- p142: mov al,[si] ; get character
- cmp al,'a' ; lower case?
- jb p144 ; no
- cmp al,'z' ; lower case?
- ja p144 ; no
- sub al,'a'-'A' ; yes - make it upper case
- mov [si],al ; put it back on the line
-
- p144: inc si ; point to next
- loop p142 ; all done?
-
- mov ax,realcs
- mov es,ax
- pop bx ; get start addr
- pop cx ; get command line length
-
- p146: mov al,[bx] ; get character
- cmp al,' ' ; is it a space?
- jz p155 ; yes
- cmp al,'*' ; is it an asterisk?
- jz p146a ; yes
- cmp al,'8' ; is it an 8 (lower-case asterisk)?
- jz p146a ; yes
- jmp p146b
-
- p146a: mov di,offset modtbl ; clear all key modifications
- mov cx,11
- mov al,0
- rep stosb ; clear mod table
- jmp p159 ; return
-
- p146b: mov si,offset tokens ; search token list
- mov dl,0 ; number of items to compare
- p147: mov dh,[si] ; get token
- cmp dh,al ; same?
- jz p148 ; yes
- inc si ; point to next token
- inc dl
- cmp dl,11 ; done?
- jnz p147 ; no
- jmp p155 ; no hit
-
- p148: ; got a valid character
- mov dh,0
- mov di,offset modtbl
- add di,dx ; got offset into table
- mov es:[di],dh ; clear current setting
- mov dh,[bx+1] ; get next character
- cmp dh,'+' ; is it a plus?
- jnz p149 ; no
- mov dh,2 ; set it on
- jmp p150
- p149: cmp dh,'-' ; is it a minus?
- jnz p155 ; no
- mov dh,1 ; set it off
- p150: mov es:[di],dh ; change mod table
-
- p155: inc bx ; point to next char
- loop p146 ; done?
-
- p159: ret
- p140 endp
-
- p160 proc near ; turn suspend off
- push ax
- push es
- push di
- mov ax,40h
- mov es,ax
- mov di,17h ; point to keyboard flag
- mov al,es:[di] ; keyboard state - flag in al
- and al,0efh ; turn suspend off
- mov es:[di],al ; re-set state
- pop di
- pop es
- pop ax
- ret
- p160 endp
-
- p180 proc near ; display status of keys
- mov ax,realcs ; get real code segment
- mov es,ax ; get code seg in es
- mov cx,11 ; items to display
- mov di,offset modtbl ; point to mod table
- mov dx,offset dummy1 ; point to first message
-
- p181:
- mov si,dx
- mov al,[si] ; get first char of message
- cmp al,255 ; no show?
- jz p185 ; yes
- call p200 ; print key name(s)
- push dx
- mov al,es:[di]
- cmp al,0
- jb p182 ; out of range
- cmp al,2
- jbe p183
- p182: mov al,2
- p183: push cx
- mov cl,4
- mov ah,0
- rol al,cl ; convert number to message offset
- pop cx
- mov dx,offset statemsg
- add dx,ax
- call p200 ; print status message
- pop dx ; get part 1 address
- p185: add dx,18 ; point to next one
- inc di ; point to next status byte
- loop p181 ; go back for more...
- ret
- p180 endp
-
- p200 proc near ; display message
- push ax
- mov ah,9
- int 21h
- pop ax
- ret
- p200 endp
-
- dummy1 db 255,' $' ; key names
- capsmsg db 'Caps Lock (U):$'
- numlmsg db 'Num Lock (N):$'
- dummy2 db 255,' $'
- altkmsg db 'Alt key (A):$'
- ctrlmsg db 'Ctrl key (C):$'
- lshkmsg db 'Left shift (L):$'
- rshkmsg db 'Right shift (R):$'
- bootmsg db 'Alt-Ctrl-Del (B):$'
- cbrkmsg db 'Ctrl-Break (X):$'
- suspmsg db 'Suspend (S):$'
-
- statemsg db ' Not affected',10,13,'$' ; status messages
- db ' Off ',10,13,'$'
- db ' On ',10,13,'$'
-
- copyr db 'KEYMOD - Copyright 1983 Data Base Decisions',10,13,10,13,'$'
- install db 'Installing keyboard modifier',10,13,10,13,'$'
- realcs dw 0 ; cs of first copy of this program
- firstime db 0 ; 0 if repeat, 1 if first time (original)
- tokens db 255,'UN',255,'ACLRBXS'; commands
-
- keymod endp
- cseg ends
- end keymod
-